package log

///
// pprof 库
///
import (
	"bytes"
	"fmt"
	"os"
	"runtime/pprof"
	"runtime/trace"

	library ".."
)

// PProf 运行信息类
type PProf struct {
	PProfData *bytes.Buffer
	TraceData *bytes.Buffer
	lock      bool
}

// Init 初始化
func (P *PProf) Init() {
	// 初始化
	P.PProfData = bytes.NewBuffer([]byte{})
	P.TraceData = bytes.NewBuffer([]byte{})
	P.lock = false
	// 开始捕获
	P.Start()
}

// Start 开始捕获
func (P *PProf) Start() error {
	if !P.lock {
		// 重置
		P.lock = true
		P.PProfData.Reset()
		P.TraceData.Reset()
		// 捕获
		if err := pprof.StartCPUProfile(P.PProfData); err != nil {
			return err
		}
		if err := trace.Start(P.TraceData); err != nil {
			return err
		}
	}
	return nil
}

// Stop 停止捕获
func (P *PProf) Stop() {
	if P.lock {
		P.lock = false
		trace.Stop()
		pprof.StopCPUProfile()
	}
}

// SaveDB 保存到数据库
func (P *PProf) SaveDB(db library.DB, Name string) {
	db.SetExec("INSERT INTO "+Name+"(Time,PProf,Trace)VALUES (?,?,?)", library.Time, P.PProfData.Bytes(), P.TraceData.Bytes())
}

// SaveLog 保存到数据库
func (P *PProf) SaveLog(L DBLog) {
	db := L.GetDB()
	db.CreateTable("PProf", "PProf")
	db.SetExec("INSERT INTO PProf(Time,PProf,Trace)VALUES (?,?,?)", library.Time, P.PProfData.Bytes(), P.TraceData.Bytes())
}

// SaveFile 保存文件
func (P *PProf) SaveFile(file string) error {
	// 保存PProf信息
	f, err := os.Create(file + ".prof")
	if err != nil {
		return fmt.Errorf("保存CPU信息文件错误: %v", err)
	}
	f.Write(P.PProfData.Bytes())
	f.Close()
	// 保存Trace信息
	f, err = os.Create(file + ".out")
	if err != nil {
		return fmt.Errorf("保存Heap信息文件错误: %v", err)
	}
	f.Write(P.TraceData.Bytes())
	f.Close()
	return nil
}
